home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / oogl / util / ppopen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-04  |  2.1 KB  |  94 lines

  1. /*
  2.  * int ppopen(char *pgm,  FILE **frompgm, FILE **topgm)
  3.  * int ppclose(FILE *fromcmd, FILE *tocmd)
  4.  *
  5.  * Like popen(), but hooks up both input and output FILE pointers to a program.
  6.  * The "program" may be any valid /bin/sh command.
  7.  * ppopen() returns the program's process id if successful, else 0.
  8.  * If successful, ``*frompgm'' and ``*topgm'' are filled in with FILE *'s
  9.  *
  10.  * Take care when using this; deadlock is possible if the program writes a
  11.  * large amount of data (> about 8K bytes) to its output while you're still
  12.  * writing to its input.
  13.  *
  14.  * Typical usage might be:
  15.  * FILE *frompgm, *topgm;
  16.  * ppopen("polymerge", &frompgm, &topgm);
  17.  * GeomFSave(g, topgm, "polymerge");
  18.  * gg = GeomFLoad(frompgm, "polymerged data");
  19.  * ppclose(topgm, frompgm);
  20. */
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <sys/wait.h>
  26.  
  27. static int npps = 0;
  28. static unsigned short *pps;
  29.  
  30. int
  31. ppopen(char *cmd, FILE **frompgm, FILE **topgm)
  32. {
  33.   struct pipe { int r, w; } pfrom, pto;
  34.   int i, pid;
  35.   
  36.  
  37.   /* create the communication pipes */
  38.   pfrom.r = pfrom.w = -1;
  39.   if(pipe(&pfrom) < 0 || pipe(&pto) < 0) {
  40.     perror("Can't make pipe");
  41.     close(pfrom.r); close(pfrom.w);
  42.     return 0;
  43.   }
  44.  
  45.   switch(pid = fork()) {
  46.   case -1:
  47.     perror("Can't fork");
  48.     return 0;
  49.  
  50.   case 0: {
  51.     static char rats[] = "Can't exec external module: ";
  52.     close(pfrom.r);
  53.     close(pto.w);
  54.     dup2(pto.r, 0);
  55.     dup2(pfrom.w, 1);
  56.     execl("/bin/sh", "sh", "-c", cmd, NULL);
  57.  
  58.     write(2, rats, sizeof(rats)-1);
  59.     perror(cmd);
  60.     exit(1);
  61.       }
  62.   }
  63.  
  64.   close(pto.r);
  65.   close(pfrom.w);
  66.   *frompgm = fdopen(pfrom.r, "r");
  67.   *topgm = fdopen(pto.w, "w");
  68.   if(pfrom.r < npps) {
  69.     int newsize = (pfrom.r + 10)*sizeof(pps[0]);
  70.     npps = pfrom.r + 10;
  71.     pps = (unsigned short *) (pps ? realloc(pps, newsize) : malloc(newsize));
  72.     bzero(&pps[npps], newsize - npps*sizeof(pps[0]));
  73.     pps[pfrom.r] = pid;
  74.   }
  75.   return pid;
  76. }
  77.  
  78. ppclose(FILE *frompgm, FILE *topgm)
  79. {
  80.   union wait w;
  81.   unsigned int fd;
  82.   int pid;
  83.  
  84.   if(frompgm == NULL) return -1;
  85.   if(topgm) fclose(topgm);
  86.   fd = fileno(frompgm);
  87.   fclose(frompgm);
  88.   if(fd < npps && pps[fd] != 0) {
  89.     pps[fd] = 0;
  90.     while((pid = wait(&w)) != pps[fd] && pid > 0)
  91.         ;
  92.   }
  93. }
  94.